Skip to content

Add reusable loopback development auth - #4360

Closed
t3dotgg wants to merge 3 commits into
mainfrom
t3code/53440ffe
Closed

Add reusable loopback development auth#4360
t3dotgg wants to merge 3 commits into
mainfrom
t3code/53440ffe

Conversation

@t3dotgg

@t3dotgg t3dotgg commented Jul 23, 2026

Copy link
Copy Markdown
Member

Summary

  • derive a stable public development key from the canonical worktree path and print reusable web/iOS/Android pairing URLs from the dev runner
  • seed that key as a process-lifetime administrative bootstrap grant only when explicitly enabled on a loopback bind
  • namespace dev browser cookies by backend port and auto-submit mobile pairing deep links through the existing onboarding flow
  • update the web/mobile agent testing skills and include the reviewed implementation plan

The development key intentionally assumes a single-user development machine. It is not a production secret, and server config rejects it on wildcard, LAN, Tailnet, or other non-loopback binds. Real pairing remains unchanged.

Verification

  • vp test run scripts/dev-runner.test.ts apps/server/src/cli/config.test.ts apps/server/src/auth/PairingGrantStore.test.ts apps/server/src/auth/EnvironmentAuthPolicy.test.ts apps/server/src/startupAccess.test.ts apps/mobile/src/features/connection/pairing.test.ts (66 tests)
  • affected package typechecks: shared, server, mobile, scripts
  • targeted lint, formatting, and git diff --check
  • web: reused the same printed pairing URL in two fresh browser tabs; both reached the authenticated home
  • iOS Simulator: rebuilt the dev client, opened the printed iOS pairing URL, and confirmed the app connected to the isolated backend
  • Fable review via Claude Code; addressed lifetime, shared loopback predicate, and repeated deep-link findings

Note

Add reusable loopback development auth for simulators and emulators

  • Introduces a dev auth system where T3CODE_DEV_AUTH=1 and a stable T3CODE_DEV_AUTH_KEY (SHA-256 of the worktree root) are injected by the dev runner when binding to the loopback host, enabling reusable pairing without one-time tokens.
  • The server seeds a reusable administrative desktop-bootstrap grant under devAuthKey at startup with unbounded uses and a far-future expiration, so simulators/emulators can reconnect via a stable deep link.
  • Adds isLoopbackAddress, isLoopbackHost, isWildcardHost, and formatHostForUrl utilities to @t3tools/shared/networkHost, and migrates startupAccess.ts to use them; renames the preview-scoped isLoopbackHost to isPreviewLocalHost to avoid collision.
  • Session cookie names are port-namespaced when devAuthKey is configured, isolating dev sessions by port.
  • Risk: the reusable credential is refused on non-loopback hosts and when Tailscale Serve is enabled; physical devices must still use real one-time pairing.

Macroscope summarized 7c9a298.


Note

High Risk
Introduces a reusable administrative bootstrap grant and dev-only auth wiring; risk is mitigated by explicit env flags, loopback-only binding checks, and Tailscale Serve rejection, but misconfiguration could still widen local privilege.

Overview
Adds worktree-scoped reusable dev authentication so agents and local tooling can pair web and simulators without burning one-time tokens.

The dev runner derives a stable key from the canonical worktree path (sha256("t3-dev:" + root)), sets T3CODE_DEV_AUTH / T3CODE_DEV_AUTH_KEY only for dev / dev:server bound to 127.0.0.1, and logs reusable web, iOS, and Android pairing URLs. Non-127.0.0.1 hosts skip dev auth (physical LAN still uses real pairing).

The server reads devAuthKey from config, seeds an unlimited administrative bootstrap grant in PairingGrantStore (same exchange path as desktop bootstrap), and suffixes session cookies by port when dev auth is on so parallel backends do not clobber cookies. Startup rejects dev auth without a key, on non-loopback binds, or with Tailscale Serve.

Mobile connections/new accepts a pairingUrl param and auto-runs the existing connect flow once per URL. Agent skills and a new implementation plan document describe reusable URLs vs one-time recovery.

Shared adds @t3tools/shared/networkHost with a strict isLoopbackAddress for dev-auth policy; preview code renames loopback checks to isPreviewLocalHost so preview behavior stays separate.

Reviewed by Cursor Bugbot for commit 7c9a298. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • New Features

    • Added reusable development authentication for loopback web servers.
    • Dev tools now display reusable web, iOS, and Android connection URLs.
    • Mobile simulators and emulators can automatically connect using pairing URLs.
    • Physical-device pairing continues to support fresh, one-time credentials.
    • Added safeguards requiring development authentication to use loopback hosts.
  • Bug Fixes

    • Prevented repeated automatic pairing attempts in the mobile connection flow.
  • Documentation

    • Updated web and mobile testing guidance, troubleshooting steps, and authentication security recommendations.
    • Added an implementation plan for development authentication.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title is concise and accurately summarizes the main change: reusable loopback development auth.
Description check ✅ Passed It explains what changed, why, and how it was verified, though it doesn't follow the exact template headings.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch t3code/53440ffe

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Jul 23, 2026
Comment thread scripts/dev-runner.ts
Comment thread packages/shared/src/networkHost.ts Outdated
@t3dotgg
t3dotgg marked this pull request as ready for review July 23, 2026 11:10

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6ddeaf0. Configure here.

Comment thread packages/shared/src/networkHost.ts
Comment thread packages/shared/src/networkHost.ts
@macroscopeapp

macroscopeapp Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR modifies authentication logic in apps/server/src/auth/, adding a new reusable development authentication mechanism. Changes to auth directories are treated as sensitive and warrant human review regardless of the guardrails in place.

You can customize Macroscope's approvability policy. Learn more.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/server/src/auth/PairingGrantStore.test.ts (1)

201-221: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the reusable grant’s full shape on the second consume.

The test checks only second.subject; a regression could return the wrong method or reduced scopes after reuse while still passing.

Suggested assertions
       expect(second.subject).toBe("development-bootstrap");
+      expect(second.method).toBe("desktop-bootstrap");
+      expect(second.scopes).toEqual(first.scopes);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/server/src/auth/PairingGrantStore.test.ts` around lines 201 - 221,
Expand the assertions for the second consume in the “seeds the development
credential” test to verify its full grant shape, including method, subject, and
complete scopes. Match the existing first-grant expectations so reuse is
confirmed to preserve all grant fields.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/shared/src/networkHost.ts`:
- Around line 1-13: Update packages/shared/src/networkHost.ts at lines 1-13 so
isLoopbackHost accepts only validated loopback address literals, returning false
for omitted hosts and rejecting hostname-like values such as
127.attacker.example; update apps/server/src/cli/config.ts at lines 362-368 to
require an explicit validated loopback bind before enabling dev auth; update
scripts/dev-runner.ts at lines 326-334 to provision dev auth only with an
explicit 127.0.0.1 bind, otherwise leave it disabled; add regression coverage
for an omitted host and 127.attacker.example.

---

Nitpick comments:
In `@apps/server/src/auth/PairingGrantStore.test.ts`:
- Around line 201-221: Expand the assertions for the second consume in the
“seeds the development credential” test to verify its full grant shape,
including method, subject, and complete scopes. Match the existing first-grant
expectations so reuse is confirmed to preserve all grant fields.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: e6601f36-61f6-4463-aa10-624815e2af0c

📥 Commits

Reviewing files that changed from the base of the PR and between 1c9a6de and 6ddeaf0.

📒 Files selected for processing (21)
  • .agents/skills/test-t3-app/SKILL.md
  • .agents/skills/test-t3-mobile/SKILL.md
  • .plans/21-agent-dev-auth.html
  • apps/mobile/src/features/connection/ConnectionsNewRouteScreen.tsx
  • apps/server/src/auth/EnvironmentAuthPolicy.test.ts
  • apps/server/src/auth/EnvironmentAuthPolicy.ts
  • apps/server/src/auth/PairingGrantStore.test.ts
  • apps/server/src/auth/PairingGrantStore.ts
  • apps/server/src/auth/SessionStore.ts
  • apps/server/src/auth/utils.ts
  • apps/server/src/bin.test.ts
  • apps/server/src/cli/config.test.ts
  • apps/server/src/cli/config.ts
  • apps/server/src/config.ts
  • apps/server/src/environment/ServerEnvironment.test.ts
  • apps/server/src/server.test.ts
  • apps/server/src/startupAccess.ts
  • packages/shared/package.json
  • packages/shared/src/networkHost.ts
  • scripts/dev-runner.test.ts
  • scripts/dev-runner.ts

Comment thread packages/shared/src/networkHost.ts Outdated
@t3dotgg

t3dotgg commented Jul 30, 2026

Copy link
Copy Markdown
Member Author

Closing because reusable loopback admin credentials have been overtaken by isolated dev state, safe sharing, and recoverable one-time pairing in #4555/#4556/#4955. The explicit pairing model is simpler and matches the current testing workflow.

@t3dotgg t3dotgg closed this Jul 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant